home *** CD-ROM | disk | FTP | other *** search
- # Source Generated with Decompyle++
- # File: in.pyo (Python 2.5)
-
- from struct import unpack, pack
- from jabber.filetransfer.S5BFileXferHandler import SocketEventMixin
- import functools
- import common
- from socket import AF_INET, SOCK_STREAM
- import AsyncoreThread
- from hashlib import sha1
- from functools import partial
- from threading import RLock
- from util import lock, get_ips_s
- from logging import getLogger
- log = getLogger('jabber.filetransfer.s5bserver')
-
- class ProxyFailure(StopIteration):
- pass
-
-
- def this(f):
-
- def wrapper1(self, *args, **kw):
- return f(self(), *args, **kw)
-
- wrapper1 = (functools.wraps(f),)(wrapper1)
- return wrapper1
-
-
- class JabberS5BServerSocket(common.socket):
- _this = None
- started = False
- _lock = RLock()
- bind_addr = ('', 0)
- waiting_hashs = []
- connected_hashs = { }
-
- def __init__(self, addr = None):
- if self() is None:
- if addr is not None:
- type(self).bind_addr = ('', 0)
-
- common.socket.__init__(self, False)
- type(self)._this = self
-
-
-
- def __call__(self):
- return type(self)._this
-
-
- def start(self):
- if not self.started:
- self.started = True
- self.create_socket(AF_INET, SOCK_STREAM)
-
- try:
- self.bind(self.bind_addr)
- except Exception:
- e = None
- self.log_info('failed to bind on (%r, %r)' % self.bind_addr)
- raise e
-
- self.listen(5)
- AsyncoreThread.start()
-
-
- start = this(lock(start))
-
- def stop(self):
- if self.started:
- self.started = False
- self.close()
-
-
- stop = this(lock(stop))
-
- def handle_accept(self):
- log.info('handle_accept')
- accepted = self.accept()
- self.listen(5)
- (connected_socket, address) = accepted
- self._on_accept(connected_socket, address)
-
-
- def _on_accept(self, sock, addr):
- log.info('accept from (%r, %r)', sock, addr)
- S5BIncomingSocket(sock, addr, self)
-
-
- def conn_id(self, stream_id, initiator_jid, target_sid):
- return sha1(stream_id + initiator_jid.as_unicode() + target_sid.as_unicode()).hexdigest()
-
-
- def __del__(self):
- self.stop()
- superdel = getattr(common.socket, '__del__', None)
- if superdel is not None:
- superdel(self)
-
-
- __del__ = this(__del__)
-
- def add_hash(self, hash):
- log.info('adding hash: %s', hash)
- self.waiting_hashs.append(hash)
- if not self.started:
- self.start()
-
-
- add_hash = this(lock(add_hash))
-
- def hash_waiting(self, hash, conn):
- log.info('waiting hash: %s', hash)
- self.waiting_hashs.remove(hash)
- if not self.waiting_hashs:
- self.stop()
-
- self.connected_hashs[hash] = conn
-
- hash_waiting = this(lock(hash_waiting))
-
- def check_hash(self, hash):
- return hash in self.connected_hashs
-
- check_hash = this(lock(check_hash))
-
- def retrieve_hash(self, hash):
- log.info('retrieving hash: %s', hash)
- if hash in self.connected_hashs:
- return self.connected_hashs.pop(hash)
- else:
-
- try:
- self.waiting_hashs.remove(hash)
- return False
- except ValueError:
- return None
- finally:
- if not self.waiting_hashs:
- self.stop()
-
-
-
- retrieve_hash = this(lock(retrieve_hash))
-
- def hosts(self):
- port = self.socket.getsockname()[1]
- return [ (ip, port) for ip in get_ips_s() ]
-
- hosts = property(this(hosts))
-
-
- class S5BIncomingSocket(common.socket, SocketEventMixin):
-
- def __init__(self, sock, addr, server):
- SocketEventMixin.__init__(self)
- common.socket.__init__(self, sock)
- self.server = server
- self.data = None
- self.proc(self.s5b_ok())
-
-
- def s5b_ok(self):
- yield (2, None)
- greeting = None
- (_head, num_authmethods) = unpack('BB', greeting)
- yield (num_authmethods, '')
- methods = None
- authmethods = unpack('%dB' % num_authmethods, methods)
- if 0 not in authmethods:
- yield (0, pack('BB', 5, 255))
- raise ProxyFailure('bad auth methods')
- else:
- yield (4, pack('BB', 5, 0))
- auth = None
- (_head, tcp, reserved, type_) = unpack('4B', auth)
- if not (_head == 5) and tcp == 1 and reserved == 0 and type_ == 3:
- raise ProxyFailure('bad address header')
-
- yield (1, '')
- (len_,) = None(unpack, 'B')
- yield (len_ + 2, '')
- (addr, _port) = None(unpack, '%dsH' % len_)
- self.hash = addr
- if self.server.check_hash(self.hash):
- raise ProxyFailure('hash already connected')
-
-
- self.collect_incoming_data = lambda _data: pass
- strng = pack('=4B%dpH' % (len_ + 1,), 5, 0, 0, 3, addr, 0)
- yield (False, strng)
-
-
- def proc(self, gen):
-
- try:
- (to_read, out_bytes) = gen.send(self.data)
- except ProxyFailure:
- self.close()
- return None
- except StopIteration:
-
- try:
- self.handle_expt = self.post_connect_expt
- self.handle_error = self.post_connect_error
- self.handle_close = self.post_connect_close
- self.do_disconnect = self.post_connect_disconnect
- self.server.hash_waiting(self.hash, self)
- except ValueError:
- self.close()
-
- return None
-
- bytes = str(out_bytes)
- print 'out_bytes', out_bytes, 'bytes', bytes
- if out_bytes:
- self.push(bytes)
-
- self.data = ''
- self.found_terminator = partial(self.proc, gen)
- if to_read is False:
- log.info('found to_read is False, generator exhausted')
-
- self.found_terminator = lambda : pass
-
- self.collect_incoming_data = lambda _data: pass
- self.set_terminator(0)
-
- try:
- self.handle_expt = self.post_connect_expt
- self.handle_error = self.post_connect_error
- self.handle_close = self.post_connect_close
- self.do_disconnect = self.post_connect_disconnect
- self.server.hash_waiting(self.hash, self)
- except ValueError:
- self.close()
- except:
- None<EXCEPTION MATCH>ValueError
-
-
- None<EXCEPTION MATCH>ValueError
- if isinstance(to_read, int):
- self.set_terminator(to_read)
- else:
- self.set_terminator(to_read._size())
-
-
- def collect_incoming_data(self, data):
- self.data += data
-
-
- def __del__(self):
- self.close()
- common.socket.__del__(self)
-
-
-